#region Copyright (c) 2003, newtelligence AG. All rights reserved.

/*
// Copyright (c) 2003, newtelligence AG. (http://www.newtelligence.com)
// Original BlogX Source Code: Copyright (c) 2003, Chris Anderson (http://simplegeek.com)
// All rights reserved.
//  
// Redistribution and use in source and binary forms, with or without modification, are permitted 
// provided that the following conditions are met: 
//  
// (1) Redistributions of source code must retain the above copyright notice, this list of 
// conditions and the following disclaimer. 
// (2) Redistributions in binary form must reproduce the above copyright notice, this list of 
// conditions and the following disclaimer in the documentation and/or other materials 
// provided with the distribution. 
// (3) Neither the name of the newtelligence AG nor the names of its contributors may be used 
// to endorse or promote products derived from this software without specific prior 
// written permission.
//      
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// -------------------------------------------------------------------------
//
// Original BlogX source code (c) 2003 by Chris Anderson (http://simplegeek.com)
// 
// newtelligence is a registered trademark of newtelligence Aktiengesellschaft.
// 
// For portions of this software, the some additional copyright notices may apply 
// which can either be found in the license.txt file included in the source distribution
// or following this notice. 
//
*/

#endregion

using System;
using System.Collections;
using System.Xml.Serialization;

namespace newtelligence.DasBlog.Runtime
{
	[XmlRoot(Namespace=Data.NamespaceURI)]
	[XmlType(Namespace=Data.NamespaceURI)]
	[Serializable]
	public class Attachment
	{
		private string name;
		private string url;
		private string type;
		private long length;
		private AttachmentType attachmentType;

		public string Name
		{
			get { return this.name; }
			set { this.name = value; }
		}

		[XmlIgnore]
		public string Url
		{
			get { return this.url; }
			set { this.url = value; }
		}

		public string Type
		{
			get { return this.type; }
			set { this.type = value; }
		}

		public long Length
		{
			get { return this.length; }
			set { this.length = value; }
		}

		public AttachmentType AttachmentType { get { return attachmentType; } set { attachmentType = value; } }
		[XmlIgnore]
		public bool AttachmentTypeSpecified { get { return attachmentType != AttachmentType.Unknown; } set { if ( !value ) attachmentType = AttachmentType.Unknown; }} 


		public Attachment()
		{
		}

		public Attachment(string name, string type, long length, AttachmentType attachmentType)
		{
			this.name = name;
			this.type = type;
			if (length != 0) this.length = length;
			this.attachmentType = attachmentType;
		}
	}

	[Serializable]
	public class AttachmentCollection : CollectionBase
	{
		/// <summary>
		/// Initializes a new empty instance of the AttachmentCollection class.
		/// </summary>
		public AttachmentCollection()
		{
			// empty
		}

		/// <summary>
		/// Initializes a new instance of the AttachmentCollection class, containing elements
		/// copied from an array.
		/// </summary>
		/// <param name="items">
		/// The array whose elements are to be added to the new AttachmentCollection.
		/// </param>
		public AttachmentCollection(Attachment[] items)
		{
			this.AddRange(items);
		}

		/// <summary>
		/// Initializes a new instance of the AttachmentCollection class, containing elements
		/// copied from another instance of AttachmentCollection
		/// </summary>
		/// <param name="items">
		/// The AttachmentCollection whose elements are to be added to the new AttachmentCollection.
		/// </param>
		public AttachmentCollection(AttachmentCollection items)
		{
			this.AddRange(items);
		}

		/// <summary>
		/// Adds the elements of an array to the end of this AttachmentCollection.
		/// </summary>
		/// <param name="items">
		/// The array whose elements are to be added to the end of this AttachmentCollection.
		/// </param>
		public virtual void AddRange(Attachment[] items)
		{
			foreach (Attachment item in items)
			{
				this.List.Add(item);
			}
		}

		/// <summary>
		/// Adds the elements of another AttachmentCollection to the end of this AttachmentCollection.
		/// </summary>
		/// <param name="items">
		/// The AttachmentCollection whose elements are to be added to the end of this AttachmentCollection.
		/// </param>
		public virtual void AddRange(AttachmentCollection items)
		{
			foreach (Attachment item in items)
			{
				this.List.Add(item);
			}
		}

		/// <summary>
		/// Adds an instance of type Attachment to the end of this AttachmentCollection.
		/// </summary>
		/// <param name="value">
		/// The Attachment to be added to the end of this AttachmentCollection.
		/// </param>
		public virtual void Add(Attachment value)
		{			
			this.List.Add(value);
		}

		/// <summary>
		/// Determines whether a specfic Attachment value is in this AttachmentCollection.
		/// </summary>
		/// <param name="value">
		/// The Attachment value to locate in this AttachmentCollection.
		/// </param>
		/// <returns>
		/// true if value is found in this AttachmentCollection;
		/// false otherwise.
		/// </returns>
		public virtual bool Contains(Attachment value)
		{
			return this.List.Contains(value);
		}

		/// <summary>
		/// Return the zero-based index of the first occurrence of a specific value
		/// in this AttachmentCollection
		/// </summary>
		/// <param name="value">
		/// The Attachment value to locate in the AttachmentCollection.
		/// </param>
		/// <returns>
		/// The zero-based index of the first occurrence of the _ELEMENT value if found;
		/// -1 otherwise.
		/// </returns>
		public virtual int IndexOf(Attachment value)
		{
			return this.List.IndexOf(value);
		}

		/// <summary>
		/// Inserts an element into the AttachmentCollection at the specified index
		/// </summary>
		/// <param name="index">
		/// The index at which the Attachment is to be inserted.
		/// </param>
		/// <param name="value">
		/// The Attachment to insert.
		/// </param>
		public virtual void Insert(int index, Attachment value)
		{
			this.List.Insert(index, value);
		}

		/// <summary>
		/// Gets or sets the Attachment at the given index in this AttachmentCollection.
		/// </summary>
		public virtual Attachment this[int index]
		{
			get { return (Attachment) this.List[index]; }
			set { this.List[index] = value; }
		}

		/// <summary>
		/// Removes the first occurrence of a specific Attachment from this AttachmentCollection.
		/// </summary>
		/// <param name="value">
		/// The Attachment value to remove from this AttachmentCollection.
		/// </param>
		public virtual void Remove(Attachment value)
		{
			this.List.Remove(value);
		}

		protected override void OnValidate( Object value )  
		{
			int count = 0;
			foreach (Attachment attachment in this.List)
			{
				if (attachment.AttachmentType == AttachmentType.Enclosure) count++;
			}

			if (count > 1)
				throw new ArgumentException( "Only one Enclosure is allowed per collection" );
		}

		/// <summary>
		/// Type-specific enumeration class, used by AttachmentCollection.GetEnumerator.
		/// </summary>
		public class Enumerator : IEnumerator
		{
			private IEnumerator wrapped;

			public Enumerator(AttachmentCollection collection)
			{
				this.wrapped = ((CollectionBase) collection).GetEnumerator();
			}

			public Attachment Current
			{
				get { return (Attachment) (this.wrapped.Current); }
			}

			object IEnumerator.Current
			{
				get { return (Attachment) (this.wrapped.Current); }
			}

			public bool MoveNext()
			{
				return this.wrapped.MoveNext();
			}

			public void Reset()
			{
				this.wrapped.Reset();
			}
		}

		/// <summary>
		/// Returns an enumerator that can iterate through the elements of this AttachmentCollection.
		/// </summary>
		/// <returns>
		/// An object that implements System.Collections.IEnumerator.
		/// </returns>        
		new public virtual Enumerator GetEnumerator()
		{
			return new Enumerator(this);
		}
	}
}